package com.dq.service.order.impl;

import com.dq.context.Constant;
import com.dq.exception.customException.AdminException;
import com.dq.controller.in.orders.UserOrderReturnQuery;
import com.dq.controller.in.orders.UserOrderReturnSave;
import com.dq.controller.in.base.BaseAdminQuery;
import com.dq.vo.ListDataVo;
import com.dq.vo.Vo;
import com.dq.vo.baseVo.VO;
import com.dq.domain.base.impl.BaseDaoImpl;
import com.dq.domain.orders.Orders;
import com.dq.domain.orders.UserOrder;
import com.dq.domain.orders.UserOrderReturn;
import com.dq.domain.orders.info.OrderInfo;
import com.dq.domain.org.Org;
import com.dq.domain.record.ProfitRecord;
import com.dq.domain.goods.stock.StockChangeRecord;
import com.dq.domain.sys.user.user.base.SysUser;
import com.dq.domain.sys.user.user.WxUser;
import com.dq.repository.BaseRepositories;
import com.dq.repository.record.ProfitRecordRepository;
import com.dq.service.order.UserOrderReturnService;
import com.dq.service.org.OrgService;
import com.dq.service.sys.user.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author cf
 *
 */
@Service
public class UserOrderReturnServiceImpl extends BaseRepositories implements UserOrderReturnService {
    @Autowired
    private OrgService orgService;
    @Autowired
    private SysUserService sysUserService;
    @PersistenceContext
    private EntityManager entityManager;
    @Autowired
    private ProfitRecordRepository profitRecordRepository;

    /**
     * 退货单列表
     */
    @Override
    public Vo list(UserOrderReturnQuery userOrderReturnQuery) throws AdminException {
        userOrderReturnQuery.format();
        Map<String, Object> query = userOrderReturnQuery.parseMap();

        // todo 状态：审核通过显示审核通过和完成状态
        if(userOrderReturnQuery.getStatus() != null && userOrderReturnQuery.getStatus().name.equals(UserOrderReturn.OrderReStatus.pass.name)) {
            List<UserOrderReturn.OrderReStatus> statusList = new ArrayList<>();
            statusList.add(UserOrderReturn.OrderReStatus.end);
            statusList.add(UserOrderReturn.OrderReStatus.pass);
            query.put("status" + BaseDaoImpl.inSqlStr, statusList);
            query.remove("status");
        }

        if(userOrderReturnQuery.getOrgId() != null) {
            query.put("org_id", userOrderReturnQuery.getOrgId());
            query.remove("orgId");
        }else {
            // 只显示负责门店信息
            List<Org> orgList = orgService.getListAllByUser();
            if(orgList == null || orgList.size() <= 0) {
                throw new AdminException("此账号无负责门店");
            }
            query.put("org" + BaseDaoImpl.inSqlStr, orgList);
        }

        if(StringUtils.isNotBlank(userOrderReturnQuery.getUserOrdersNo())) {
            query.put("userOrders_ordersNo", userOrderReturnQuery.getUserOrdersNo());
            query.remove("userOrdersNo");
        }
        if(StringUtils.isNotBlank(userOrderReturnQuery.getWxuserNo())) {
            query.put("wxUser_cardNo", userOrderReturnQuery.getWxuserNo());
            query.remove("wxuserNo");
        }
        if(StringUtils.isNotBlank(userOrderReturnQuery.getWxuserName())) {
            query.put("wxUser_userRealcName" + BaseDaoImpl.likeSqlStr, "%"+BaseAdminQuery.likeSql(userOrderReturnQuery.getWxuserName())+"%");
            query.remove("wxuserName");
        }
        if(userOrderReturnQuery.getUserOrderReturnBeginTime() != null) {
            query.put("createTime" + BaseDaoImpl.gteSqlStr, userOrderReturnQuery.getUserOrderReturnBeginTime());
            query.remove("userOrderReturnBeginTime");
        }
        if(userOrderReturnQuery.getUserOrderReturnEndTime() != null) {
            query.put("createTime" + BaseDaoImpl.lteSqlStr, userOrderReturnQuery.getUserOrderReturnEndTime());
            query.remove("userOrderReturnEndTime");
        }
        if(StringUtils.isNotBlank(userOrderReturnQuery.getSearchBox())) {
            Map<String, Object> keyQuery = new HashMap<>(16);

            keyQuery.put("ordersNo", userOrderReturnQuery.getSearchBox());
            keyQuery.put("userOrders_ordersNo", userOrderReturnQuery.getSearchBox());
            keyQuery.put("wxUser_cardNo", userOrderReturnQuery.getSearchBox());
            keyQuery.put("wxUser_userRealcName" + BaseDaoImpl.likeSqlStr, BaseAdminQuery.likeSql(userOrderReturnQuery.getSearchBox()));

            query.put("keyQuery" + BaseDaoImpl.orAndSqlStr, keyQuery);
            query.remove("searchBox");
        }

        List<UserOrderReturn> list = dao.find(dao.query2Hql(UserOrderReturn.class, query), query);
        Long count = dao.count(dao.count2Hql(UserOrderReturn.class, query), query);

        return new ListDataVo((List<UserOrderReturn.Vo>) VO.toVOCollection(list), count);
    }

    /**
     * 获取退货单详情
     * @param userOrderId
     * @return
     */
    @Override
    public List<OrderInfo.OrgOrderInfoVo> getUserOrderInfo(Long userOrderId) {
        Map<String, Object> query = new HashMap<>(16);
        query.put("orders_id", userOrderId);

        List<OrderInfo.OrgOrderInfoVo> voList = new ArrayList<>();
        List<OrderInfo> list = dao.find(dao.query2Hql(OrderInfo.class, query), query);
        for (OrderInfo orderInfo : list) {
            voList.add(orderInfo.toOrgOrderInfoVo());
        }
        return voList;
    }

    /**
     *  退货单 生成逻辑 001: 设置退货单/子单对象属性, 现在无线上退货逻辑，审核通过直接更改状态为【退货完成】
     * @param userOrderReturnSave
     * @return
     * @throws AdminException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserOrderReturn manualSave(UserOrderReturnSave userOrderReturnSave, UserOrderReturn.OrderReStatus status) throws AdminException {
        if(userOrderReturnSave.getOrdersId() == null) {
            throw new AdminException("销售单id获取异常");
        }
        List<UserOrderReturnSave.UserOrderReturnInfo> returnInfoList = userOrderReturnSave.getReturnInfoList();
        if(returnInfoList == null || returnInfoList.size() <= 0) {
            throw new AdminException("退货商品为空");
        }
        if(userOrderReturnSave.getPrice() == null) {
            throw new AdminException("退款金额为空");
        }

        Map<String, Object> query = new HashMap<>(16);
        query.put("orders_id", userOrderReturnSave.getOrdersId());
        List<OrderInfo> orderInfos = dao.find(dao.query2Hql(OrderInfo.class, query), query);
        if(orderInfos == null || orderInfos.size() <= 0) {
            throw new AdminException("无对应id销售单信息");
        }

        UserOrder userOrder = (UserOrder) orderInfos.get(0).getOrders();
        if(userOrderReturnSave.getPrice().compareTo(userOrder.getPrice()) > 0) {
            throw new AdminException("退款金额大于实际支付金额");
        }
        if(userOrder.getStatus().name.equals(UserOrder.UserOrderStatus.alreadyCancel.name)
            || userOrder.getStatus().name.equals(UserOrder.UserOrderStatus.waitPay.name)
                || userOrder.getStatus().name.equals(UserOrder.UserOrderStatus.returnIng.name)
                || userOrder.getStatus().name.equals(UserOrder.UserOrderStatus.returnOver.name)
                || userOrder.getStatus().name.equals(UserOrder.UserOrderStatus.orderShutDown.name)) {
            throw new AdminException("销售单状态不支持退货");
        }

        UserOrderReturn userOrderReturn = new UserOrderReturn();
        userOrderReturn.setUserOrders(userOrder);
        userOrderReturn.setWxUser(userOrder.getWxUser());
        userOrderReturn.setStatus(status);
        userOrderReturn.setPrice(userOrderReturnSave.getPrice());
        userOrderReturn.setRemark(userOrderReturnSave.getRemark());

        List<OrderInfo> orderInfoList = new ArrayList<>();
        for (OrderInfo orderInfo : orderInfos) {
            for (UserOrderReturnSave.UserOrderReturnInfo userOrderReturnInfo : returnInfoList) {
                Long userOrderInfoId = userOrderReturnInfo.getOrdersId();
                Long returnCount = userOrderReturnInfo.getReturnCount();
                if(orderInfo.getId().toString().equals(userOrderInfoId.toString())) {
                    if(returnCount > orderInfo.getNumber()) {
                        throw new AdminException(orderInfo.getProduct().getGoods().getGoodsName() + ", 退货商品数量大于实际购买数量");
                    }
                    OrderInfo orderInfoSave = new OrderInfo();
                    orderInfoSave.setOrders(userOrderReturn);
                    orderInfoSave.setProduct(orderInfo.getProduct());
                    orderInfoSave.setGoods(orderInfo.getGoods());
                    orderInfoSave.setNumber(returnCount);
                    orderInfoSave.setAmount(orderInfo.getProduct().getPrice().multiply(new BigDecimal(String.valueOf(returnCount))).setScale(2, RoundingMode.HALF_UP));

                    orderInfoList.add(orderInfoSave);
                }
            }
        }

        // 保存退货单/子单对象
        userOrderReturn = saveMainAndInfo(userOrderReturn, orderInfoList);

        return userOrderReturn;
    }

    /**
     * 退货单 生成逻辑 002: 保存退货单/子单对象
     * 判断属性为空
     * @param
     * @return
     * @throws AdminException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserOrderReturn saveMainAndInfo(UserOrderReturn userOrderReturn, List<OrderInfo> orderInfoList) throws AdminException {
        if(orderInfoList == null || orderInfoList.size() <= 0) {
            throw new AdminException("退货子单信息为空");
        }
        if(StringUtils.isBlank(userOrderReturn.getOrdersNo())) {
            userOrderReturn.setOrdersNo(Orders.generyDatetimeAndRandomNum(Constant.ORDERS_SUFF_COUNT));
        }
        if(userOrderReturn.getUserOrders() == null) {
            throw new AdminException("退货单未关联销售单");
        }
        if(userOrderReturn.getWxUser() == null) {
            throw new AdminException("退货单未关联退货顾客");
        }
        if(userOrderReturn.getStatus() == null) {
            throw new AdminException("退货状态异常");
        }
        if(userOrderReturn.getPrice() == null) {
            throw new AdminException("退款金额为空");
        }

        userOrderReturn.setVersion(Constant.VERSION_VALUE);
        userOrderReturn.setDeleted(false);

        long passTime = System.currentTimeMillis();
        userOrderReturn.setCreateTime(passTime);
        userOrderReturn.setLastModifyTime(passTime);

        SysUser user = sysUserService.getUser();
        userOrderReturn.setCreateUser(user);
        userOrderReturn.setUpdateUser(user);

        if(userOrderReturn.getTradeSuccessTime() == null) {
            // 设置完成时间
            if(userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.end.name) || userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.noPass.name)) {
                userOrderReturn.setTradeSuccessTime(passTime);
            }
            // 设置审批时间
            if(!userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.waitPass.name)) {
                if(userOrderReturn.getPassTime() == null) {
                    userOrderReturn.setPassTime(passTime);
                }
            }
        }
        if(userOrderReturn.getOrg() == null) {
            userOrderReturn.setOrg(userOrderReturn.getUserOrders().getOrg());
        }

        Long payGoodsNum = 0L;
        List<OrderInfo> infoList = new ArrayList<>();
        for (OrderInfo orderInfo : orderInfoList) {
            infoList.add(orderInfo);
            payGoodsNum = payGoodsNum + orderInfo.getNumber();
        }

        userOrderReturn.setPayGoodsNum(payGoodsNum);
        userOrderReturn.setCateNum(Long.parseLong(String.valueOf(infoList.size())));
        this.entityManager.persist(userOrderReturn);

        for (OrderInfo orderInfo : infoList) {
            if(orderInfo.getOrders() == null) {
                orderInfo.setOrders(userOrderReturn);
            }
            orderInfo.setVersion(Constant.VERSION_VALUE);
            orderInfo.setDeleted(false);
            orderInfo.setCreateTime(passTime);
            orderInfo.setLastModifyTime(passTime);
            orderInfo.setCreateUser(user);
            orderInfo.setUpdateUser(user);

            this.entityManager.persist(orderInfo);
        }

        this.entityManager.flush();

        // 修改订单状态
        updateUserOrder(userOrderReturn);

        return userOrderReturn;
    }

    /**
     * 退单审批/退单完成
     *
     * @param id
     * @param status
     * @return
     * @throws AdminException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserOrderReturn examine(Long id, UserOrderReturn.OrderReStatus status, String remark) throws AdminException {

        if(status == null) {
            throw new AdminException("状态为空");
        }

        UserOrderReturn get = dao.get(UserOrderReturn.class, id);
        if (get == null) {
            throw new AdminException("无对应id对象");
        }

        // todo 审批通过， 直接设置为完成
        if(status.toString().equals(UserOrderReturn.OrderReStatus.pass.toString())) {
            get.setStatus(UserOrderReturn.OrderReStatus.end);
        }else {
            get.setStatus(status);
        }

        if(StringUtils.isNotBlank(remark)) {
            get.setRemark(remark);
        }
        UserOrderReturn update = update(get);

        return update;
    }

    /**
     * 修改 退货单 逻辑
     * @param userOrderReturn
     * @return
     * @throws AdminException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserOrderReturn update(UserOrderReturn userOrderReturn) throws AdminException {
        UserOrderReturn old = dao.get(UserOrderReturn.class, userOrderReturn.getId());
        if(!old.getStatus().name.equals(userOrderReturn.getStatus().name)) {
            if(old.getStatus().name.equals(UserOrderReturn.OrderReStatus.end.name)) {
                throw new AdminException("状态为已完成，不能修改状态");
            }
            if(userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.waitPass.name)) {
                throw new AdminException("状态不能再次设置为 待审核");
            }
            if(userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.pass.name)
                    || userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.noPass.name)) {
                if(!old.getStatus().name.equals(UserOrderReturn.OrderReStatus.waitPass.name)) {
                    throw new AdminException("非待审核状态， 不能进行审核");
                }
            }
            //
        }

        long tradeSuccessTime = System.currentTimeMillis();
        userOrderReturn.setLastModifyTime(tradeSuccessTime);

        SysUser user = sysUserService.getUser();
        if(user != null) {
            userOrderReturn.setUpdateUser(user);
        }

        // 设置完成时间
       if(userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.end.name) || userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.noPass.name)) {
           if(userOrderReturn.getTradeSuccessTime() == null) {
               userOrderReturn.setTradeSuccessTime(tradeSuccessTime);
           }
       }
       // 设置审批时间
       if(!userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.waitPass.name)) {
           if(userOrderReturn.getPassTime() == null) {
               userOrderReturn.setPassTime(tradeSuccessTime);
           }
       }

        dao.modify(userOrderReturn);

        // 修改订单状态
        updateUserOrder(userOrderReturn);

        // 退货完成: 自动生成库存变动记录, 修改对应商品库存
        if(userOrderReturn.getStatus().toString().equals(UserOrderReturn.OrderReStatus.end.toString())) {
            List<OrderInfo> orderInfos = orderInfoRepository.findByOrders(userOrderReturn);
            for (OrderInfo orderInfo : orderInfos) {
                orgStockChangeService.orderInfo2Stock(userOrderReturn.getOrg(), orderInfo, StockChangeRecord.ChangeDirection.add, StockChangeRecord.ChangeType.adjust);
            }
        }

        return userOrderReturn;
    }

    /**
     * 修改订单状态
     * @param userOrderReturn
     */
    private void updateUserOrder(UserOrderReturn userOrderReturn) {
        UserOrder userOrder = (UserOrder) userOrderReturn.getUserOrders();
        if(userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.end.name) || userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.noPass.name)) {
            userOrder.setStatus(UserOrder.UserOrderStatus.returnOver);
            if(userOrderReturn.getStatus().name.equals(UserOrderReturn.OrderReStatus.end.name)) {
                // 退货完成去除返佣
                less(userOrderReturn);
            }
        }else {
            userOrder.setStatus(UserOrder.UserOrderStatus.returnIng);
        }
        dao.modify(userOrder);
    }

    /**
     * 退货后
     * @param userOrderReturn
     */
    @Override
    public void less(UserOrderReturn userOrderReturn) {
        UserOrder userOrder = (UserOrder) userOrderReturn.getUserOrders();
        BigDecimal percentage = new BigDecimal("0");
        if(userOrderReturn != null && userOrder != null){
            percentage = userOrderReturn.getPrice().divide(userOrder.getPrice(),2, RoundingMode.HALF_UP);
        }
        WxUser inviteUser = (WxUser) userOrder.getWxUser().getInviteUser();
        if(inviteUser != null){
            save(userOrder,inviteUser,percentage, ProfitRecord.ChangeProfitType.rakeBack);
        }
    }
    public void save(UserOrder userOrder,WxUser inviteUser,BigDecimal percentage,ProfitRecord.ChangeProfitType changeProfitType){
        ProfitRecord byUserOrderAndUser = profitRecordRepository.findByUserOrderAndUser(userOrder, inviteUser);
        ProfitRecord profitRecord = new ProfitRecord();
        profitRecord.setUser(inviteUser);
        profitRecord.setProfitChangeType(ProfitRecord.ProfitChangeType.less);
        profitRecord.setChangeProfitType(changeProfitType);
        profitRecord.setChangeNum(byUserOrderAndUser.getChangeNum().multiply(percentage));
        profitRecord.setUserOrder(userOrder);
        profitRecordRepository.save(profitRecord);
    }

}

